#!/usr/bin/python
# -*- coding: utf-8 -*-
# Description: Description
# Create at 2008-12-16 上午12:51:18
# Author: MK2[fengmk2@gmail.com]
"""docstrings
"""
import xmlrpclib

from google.appengine.ext import db

from net4.core.xmlrpc import public
from net4 import settings
from net4.models.posts import Post

class AuthenticationError(Exception):
    """Authentication fail"""

def authenticated(pos=1):
    """
    A decorator for functions that require authentication.
    Assumes that the username & password are the second & third parameters.
    Doesn't perform real authorization (yet), it just checks that the
    user is_superuser.
    """
    def _decorate(func):
        def _wrapper(*args, **kwargs):
            username = args[pos+0]
            password = args[pos+1]
            args = args[0:pos]+args[pos+2:]
#            try:
#                user = User.objects.get(username__exact=username)
#            except User.DoesNotExist:
#                raise AuthenticationError("Authentication Failure")
#            if not user.check_password(password):
#                raise AuthenticationError("Authentication Failure")
#            if not user.is_superuser:
#                raise AuthenticationError("Authorization Failure")
            return func(username, *args, **kwargs)
        _wrapper.__name__ = func.__name__
        _wrapper.__doc__ = func.__doc__
        _wrapper.__module__ = func.__module__
        _wrapper.__dict__.update(func.__dict__)
        return _wrapper
    return _decorate

@public
@authenticated()
def metaWeblog_newPost(user, blogid, struct, publish): # blogid, username, password, struct, publish):
    """return postid
    
    >>> from xmlrpclib import ServerProxy
    >>> server = ServerProxy("http://localhost:8080/metaweblog")
    >>> server.metaWeblog.newPost('mk2', '123', 123, {}, True)
    123
    """
    return 123

@public
@authenticated()
def metaWeblog_editPost(user, postid, struct, publish):
    """returns true
    
    >>> from xmlrpclib import ServerProxy
    >>> server = ServerProxy("http://localhost:8080/metaweblog")
    >>> server.metaWeblog.editPost('mk2', '123', 123, {}, True)
    True
    """
    return True

@public
@authenticated()
def metaWeblog_getPost(user, postid):
    """returns struct
    
    >>> from xmlrpclib import ServerProxy
    >>> server = ServerProxy("http://localhost:8080/metaweblog")
    >>> server.metaWeblog.getPost('mk2', '123', 123)
    {}
    """
    post = db.get(db.Key(postid))
    return post_struct(post)
    
@public
@authenticated()
def blogger_getUsersBlogs(user, appkey):
    """
    an array of <struct>'s containing the ID (blogid), name
    (blogName), and URL (url) of each blog.
    
    >>> from xmlrpclib import ServerProxy
    >>> server = ServerProxy("http://localhost:8080/metaweblog")
    >>> server.blogger.getUsersBlogs('mk2', '123', 'test')
    [{'url': 'http://net4.appspot.com/', 'blogid': '123', 'blogName': 'net4'}]
    """
    return [{
            'blogid': user,
            'blogName': 'net4',
            'url': settings.SITE_URL
            }]

@public
@authenticated()
def metaWeblog_getCategories(user, blogid):
    """
    an array of string, contains all categories.
    
    >>> from xmlrpclib import ServerProxy
    >>> server = ServerProxy("http://localhost:8080/metaweblog")
    >>> server.metaWeblog.getCategories('mk2', '123', 123)
    ['a', 'net4', 'test']
    """
    return ['a', 'net4', 'test']

# example... this is what wordpress returns:
# {'permaLink': 'http://gabbas.wordpress.com/2006/05/09/hello-world/',
#  'description': 'Welcome to <a href="http://wordpress.com/">Wordpress.com</a>. This is your first post. Edit or delete it and start blogging!',
#  'title': 'Hello world!',
#  'mt_excerpt': '',
#  'userid': '217209',
#  'dateCreated': <DateTime u'20060509T16:24:39' at 2c7580>,
#  'link': 'http://gabbas.wordpress.com/2006/05/09/hello-world/',
#  'mt_text_more': '',
#  'mt_allow_comments': 1,
#  'postid': '1',
#  'categories': ['Uncategorized'],
#  'mt_allow_pings': 1}

def format_date(d):
    """Return iso format datetime
    
#    >>> format_date(None)
#    None
    """
    if not d: return None
    return xmlrpclib.DateTime(d.isoformat())

def post_struct(post):
    link = settings.SITE_URL + 'post/%s/' % post.key()
#    categories = post.tags.all()
    struct = {
        'postid': unicode(post.key()),
        'title': post.title,
        'link': link,
        'permaLink': link,
        'description': unicode(post.content),
        'categories': ['net4', 'mk2'],#[c.name for c in categories],
        'userid': post.author.nickname(),
        # 'mt_excerpt': '',
        # 'mt_text_more': '',
        # 'mt_allow_comments': 1,
        # 'mt_allow_pings': 1}
        }
    if post.create_date:
        struct['dateCreated'] = format_date(post.create_date)
    return struct

def setTags(post, struct):
    tags = struct.get('categories', None)
    if tags is None:
        post.tags = []
    else:
        post.tags = [Tag.objects.get(name__iexact=name) for name in tags]

@public
@authenticated(pos=2)
def blogger_deletePost(user, appkey, postid, publish):
    """
    an array of string, contains all categories.
    
    >>> from xmlrpclib import ServerProxy
    >>> server = ServerProxy("http://localhost:8080/metaweblog")
    >>> server.blogger.deletePost('mk2', '123', 'testapp', 123, True)
    True
    """
    # TODO: delete post by postid
    return True

@public
@authenticated()
def metaWeblog_newMediaObject(user, blogid, struct):
    """The input struct must contain at least three elements, name,
    type and bits. returns struct, which must contain at least one
    element, url
    
    This method isn't implemented yet, obviously.
    
    >>> from xmlrpclib import ServerProxy
    >>> server = ServerProxy("http://localhost:8080/metaweblog")
    >>> server.metaWeblog.newMediaObject('mk2', '123', 123, {})
    {}
    """
    return {}

if __name__ == '__main__':
    import doctest
    doctest.testmod()

    from xmlrpclib import ServerProxy
    server = ServerProxy("http://localhost:8080/metaweblog")
    print server.metaWeblog.getPost('mk2', '123', 'postagRuZXQ0cgoLEgRQb3N0GAEM')
#    print server.system.listMethods()
#    print server.blogger.getUsersBlogs('mk2', '123', 'test')
#    print server.system.methodHelp('metaWeblog.newPost')
#    print server.system.methodHelp()
#    print server.system.methodSignature()

